package ace.module.upms.core.impl.manager.impl;

import ace.cmp.core.constants.CoreConstant;
import ace.cmp.core.utils.SystemClockUtils;
import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.manager.spring.AbstractSpringDtoManager;
import ace.module.upms.api.model.dto.UpmsOrganizationAccountDto;
import ace.module.upms.core.impl.dao.entity.UpmsOrganizationAccount;
import ace.module.upms.core.impl.dao.repository.UpmsOrganizationAccountRepository;
import ace.module.upms.core.impl.manager.UpmsOrganizationAccountManager;
import java.util.AbstractMap.SimpleEntry;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

/**
 * 组织与账户关系 spring data jdbc querydsl rsql manager implement.
 *
 * @author Caspar
 */
@Slf4j
@AllArgsConstructor
@Component
public class UpmsOrganizationAccountManagerImpl
    extends AbstractSpringDtoManager<UpmsOrganizationAccount, Long, UpmsOrganizationAccountDto>
    implements UpmsOrganizationAccountManager {

  private final UpmsOrganizationAccountRepository upmsOrganizationAccountRepository;

  @Override
  public List<UpmsOrganizationAccount> getByUpmsAppIdAndIamAccountIdIn(Long upmsAppId, List<Long> queryIamAccountIds) {
    return this.upmsOrganizationAccountRepository.getByUpmsAppIdAndIamAccountIdIn(upmsAppId, queryIamAccountIds);
  }

  @Override
  public boolean noneMatch(List<UpmsOrganizationAccount> upmsOrganizationAccounts, Long upmsOrgId, Long iamAccountId) {
    return upmsOrganizationAccounts.stream()
        .noneMatch(roleAccount ->
            roleAccount.getIamAccountId().equals(iamAccountId) &&
                roleAccount.getUpmsOrgId().equals(upmsOrgId)
        );
  }

  @Override
  public UpmsOrganizationAccount build(Long upmsAppId, Long upmsOrgId, Long iamAccountId) {
    return UpmsOrganizationAccount.builder()
        .id(this.getNewId())
        .upmsAppId(upmsAppId)
        .upmsOrgId(upmsOrgId)
        .iamAccountId(iamAccountId)

        .updateTime(SystemClockUtils.currentTimeMillis())
        .createTime(SystemClockUtils.currentTimeMillis())
        .rowVersion(CoreConstant.DEFAULT_ROW_VERSION)
        .deleteFlag(CoreConstant.DELETE_FLAG_NOT)
        .build();
  }

  @Override
  public boolean anyMatch(List<UpmsOrganizationAccount> upmsOrganizationAccounts, List<SimpleEntry<Long, Long>> orgIdAndAccountIds) {
    return upmsOrganizationAccounts.stream()
        .anyMatch(roleAccount -> orgIdAndAccountIds.stream()
            .anyMatch(roleIdAndAccountId -> {
              Long upmsOrgId = roleIdAndAccountId.getKey();
              Long iamAccountId = roleIdAndAccountId.getValue();
              return roleAccount.getIamAccountId().equals(iamAccountId)
                  && roleAccount.getUpmsOrgId().equals(upmsOrgId);
            })
        );
  }

  @Transactional(rollbackFor = Throwable.class)
  @Override
  public void insertNewAndDeleteByIdIn(List<UpmsOrganizationAccount> newUpmsOrganizationAccounts, List<Long> deleteUpmsOrganizationAccountIds) {
    if (CollectionUtils.isNotEmpty(newUpmsOrganizationAccounts)) {
      this.upmsOrganizationAccountRepository.insert(newUpmsOrganizationAccounts, false);
    }
    this.upmsOrganizationAccountRepository.deleteAllById(deleteUpmsOrganizationAccountIds);
  }
}
